<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.5"/>
<title>NDK Programmer&#39;s Guide: ABI Management</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">NDK Programmer&#39;s Guide
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.5 -->
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;"
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('md_3__key__topics__c_p_u__support__chapter_1-section_8__a_b_is.html','');});
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">ABI Management </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><a href="#intro">Introduction</a><br/>
 <a href="#sa">Supported ABIs</a><br/>
 <a href="#gc">Generating code for a Specific ABI</a><br/>
 <a href="#am">ABI management on the Android Platform</a><br/>
</p>
<p><a class="anchor" id="intro"></a> </p>
<h2>Introduction</h2>
<p>Every piece of native code generated with the Android NDK matches a given
application binary interface ("ABI") that defines exactly how your
application's machine code is expected to interact with the system at
runtime.</p>
<p>A typical ABI describes things in <em>excruciating</em> detail, and
typically includes the following information:</p>
<ul>
<li>The CPU instruction set that the machine code should use.</li>
<li>The endianness of memory stores and loads at runtime.</li>
<li>The format of executable binaries (shared libraries, programs, etc.), and
the types of content they support.</li>
<li>Various conventions used to pass data between your code and the system.
These include alignment constraints, as well as how registers and/or the stack
are used when functions are called.</li>
<li>Alignment and size constraints for enum types, structure fields, and
arrays.</li>
<li>The list of function symbols available to your machine code at runtime,
generally from a very specifically selected set of libraries.</li>
</ul>
<p>This document lists the exact ABIs supported by the Android NDK and the
official Android platform releases.</p>
<p><a class="anchor" id="sa"></a> </p>
<h2>Supported ABIs</h2>
<h3>Overview</h3>
<p>Table 1 provides an at-a-glance overview of each ABI's supported instruction
sets and capabilities.</p>
<table class="doxtable">
<tr>
<th></th><th>Instruction Set(s) </th><th>Notes  </th></tr>
<tr>
<td><a href="#armeabi">armeabi</a> </td><td>ARMV5TE and later<br/>
Thumb-1 </td><td><b>No</b> hard float.</td></tr>
<tr>
<td><a href="#v7a">armeabi-v7a</a> </td><td>armeabi<br/>
Thumb-2<br/>
VFPv3-D16<br/>
other optional </td><td>Hard float when specified as
<code>armeabi-v7a-hard</code>.<br/>
Incompatible with ARMv5, v6 devices.</td></tr>
<tr>
<td><a href="#arm64-v8a">arm64-v8a</a> </td><td>AArch-64</td><td></td></tr>
<tr>
<td><a href="#x86">x86</a> </td><td>x86 (IA-32)<br/>
MMX<br/>
SSE/2/3<br>
SSSE3</td><td>No support for MOVBE or SSE4.</td></tr>
<tr>
<td><a href="#86-64">x86_64</a> </td><td>x86-64<br/>
MMX<br/>
SSE/2/3<br>
SSSE3<br>
SSE4.1, 4.2<br>
POPCNT</td><td></td></tr>
<tr>
<td><a href="#mips">mips</a></td><td>MIPS32r1 and later</td><td>Hard
float.</td></tr>
<tr>
<td><a href="#mips64">mips 64</a></td><td>MIPS64r6</td><td></td></tr>
</table>
<p><b>Table 1.</b> Respective ABI capabilities</p>
<p>More detailed information about each ABI appears below.</p>
<p><a class="anchor" id="armeabi"></a> </p>
<h3>armeabi</h3>
<p>This is the name of an ABI for ARM-based CPUs that support <em>at least</em>
the ARMv5TE instruction set. Please refer to the following documentation for
more details:</p>
<ul>
<li><a href="https://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf">ARM Architecture
Reference Manual</a> ("ARMARM")</li>
<li><a
href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.p
df">Procedure Call Standard for the ARM Architecture</a> ("AAPCS")</li>
<li><a
href="http://infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf
">ARM ELF File Format</a> ("ARMELF")</li>
<li><a
href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.swdev.a
bi/index.html">Application Binary Interface (ABI) for the ARM Architecture</a>
("BSABI")</li>
<li><a
href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0037c/IHI0037C_bpabi.p
df">Base Platform ABI for the ARM Architecture</a> ("BPABI")</li>
<li><a
href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0039c/IHI0039C_clibabi
.pdf">C Library ABI for the ARM Architecture</a> ("CLIABI")</li>
<li><a
href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0041d/index
.html">C++ ABI for the ARM Architecture</a> ("CPPABI")</li>
<li><a
href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043d/IHI0043D_rtabi.p
df">Run-time ABI for the ARM Architecture</a> ("RTABI")</li>
<li><a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF
System V Application Binary Interface</a> (DRAFT 2001)</li>
<li><a href="http://mentorembedded.github.com/cxx-abi/abi.html">Generic C++
ABI</a></li>
</ul>
<p>Note that the AAPCS standard defines EABI as a <em>family</em> of similar
but distinct ABIs. Also, Android follows the little-endian ARM GNU/Linux ABI as
documented in the <a
href="http://sourcery.mentor.com/sgpp/lite/arm/portal/kbattach142/arm_gnu_linux_
abi.pdf">ARM GNU/Linux Application Binary Interface Supplement</a></p>
<p>This ABI does <em>not</em> support hardware-assisted floating point
computations. Instead, all floating-point operations use software helper
functions from the compiler's <code>libgcc.a</code> static library.</p>
<p>The armeabi ABI supports ARM’s <a
href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0210c/CACBC
AAE.html">Thumb (a.k.a. Thumb-1) instruction set</a>. The NDK generates Thumb
code by default unless you specify different behavior using the
<code>LOCAL_ARM_MODE</code> variable in your <code>Android.mk</code> file (see
the <a
href="./md_3__key__topics__building__chapter_1-section_8__android_8mk.html">Andr
oid.mk section</a> for details).</p>
<p><a class="anchor" id="v7a"></a> </p>
<h3>armeabi-v7a (armeabi-v7a-hard)</h3>
<p>armeabi-v7a <em>extends</em> armeabi to include a few CPU instruction set
extensions as described in the following document:</p>
<ul>
<li><a
href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c/index
.html">ARM Architecture v7-a Reference Manual</a></li>
</ul>
<p>The instruction extensions supported by this Android-specific ABI are:</p>
<ul>
<li>The Thumb-2 instruction set extension.</li>
<li>The VFP hardware FPU instructions. More specifically, VFPv3-D16, which
corresponds to 16 dedicated 64-bit floating point registers provided by the
CPU.</li>
</ul>
<p>Other extensions described by the v7-a ARM, like <a
href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388f/Beijf
cja.html">Advanced SIMD</a> (a.k.a. NEON), VFPv3-D32, or ThumbEE are optional
to this ABI. This means that developers should check <em>at runtime</em>
whether the extensions are available. If not, they must use alternative code
paths. This check is similar to the one typically performed to check/use <a
href="http://en.wikipedia.org/wiki/MMX_(instruction_set">MMX</a>), <a
href="http://en.wikipedia.org/wiki/SSE2">SSE2</a> and other specialized
instruction sets on x86 CPUs.</p>
<p>For information about how to perform these runtime checks, refer to <a
href="./md_3__key__topics__c_p_u__support__c_p_u-_f_e_a_t_u_r_e_s.html">CPU
Features</a>. Also, for information about the NDK's support for building
NEON-capable machine code, see <a
href="md_3__key__topics__c_p_u__support__c_p_u-_a_r_m-_n_e_o_n.html">CPU-ARM-NEO
N</a>.</p>
<p>Note that armeabi-v7a uses the <code>-mfloat-abi=softfp</code> switch to
enforce the rule that all double values must be passed during function calls in
"core" register pairs, instead of dedicated FP ones. All internal computations
can be performed, however, with the FP registers, which speeds them up
greatly.</p>
<p>Although this constraint results in a modest performance hit, it ensures
compatibility with all existing armeabi binaries. If you need the additional
performance, you can specify your ABI as armeabi-v7a-hard instead. Doing so
allows you to use hard floats, while still linking with Android native APIs
that use <code>softfp</code>. For more information, look inside the
<code>Android.mk</code> file in <code>/tests/device/hard-float/jni/</code>.</p>
<p><b>NOTE:</b> The armeabi-v7a machine code does <em>not</em> run on ARMv5 or
ARMv6 based devices.</p>
<p><b>NOTE:</b> You cannot specify <code>APP_ABI</code> as both armeabi-v7a and
armeabi-v7a-hard. In either case, the build system places the shared libraries
in the <code>armeabi-v7a/</code> directory.</p>
<p><a class="anchor" id="hard"></a> </p>
<h3>armeabi-v7a-hard</h3>
<p>This variant of the armeabi-v7a ABI is unique to the NDK. The NDK build
system adds the following flags in addition to those that it uses for the
armeabi-v7a ABI. </p>
<pre class="fragment">TARGET_CFLAGS += -mhard-float -D_NDK_MATH_NO_SOFTFP=1
TARGET_LDFLAGS += -Wl,--no-warn-mismatch -lm_hard
</pre><p>All code is compiled with hard-float and linked with libm_hard.a. This
is the same math library as libm.a, except that it follows hard-float ABI
conventions. The generated shared libraries are stored in
<code>lib/armeabi-v7a/</code>.</p>
<p><a class="anchor" id="arm64-v8a"></a> </p>
<h3>arm64-v8a</h3>
<p>This ABI is for ARMv8-based CPUs that support AArch64.</p>
<p>For more information, see the <a
href="http://www.arm.com/files/downloads/ARMv8_Architecture.pdf">ARMv8
Technology Preview</a>, and contact ARM for further details.</p>
<p><a class="anchor" id="x86"></a> </p>
<h3>x86</h3>
<p>This is the name of an ABI for CPUs supporting the instruction set commonly
referred to as "x86" or "IA-32". Characteristics of this ABI include:</p>
<ul>
<li>instructions normally generated by GCC with the following compiler
flags:</li>
</ul>
<pre class="fragment">-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32
</pre><p>These flags target the the Pentium Pro instruction set, along with the
the MMX, <a
href="http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions">SSE</a>, SSE2, <a
href="http://en.wikipedia.org/wiki/SSE3">SSE3</a>, and <a
href="http://en.wikipedia.org/wiki/SSSE3">SSSE3</a> instruction set extensions.
The generated code is a balanced optimization across the top Intel 32-bit
CPUs.</p>
<p><b>NOTE:</b> The compiler flags shown above do not represent a comprehensive
list. In particular, they do not include compiler optimization options used by
default and/or recommended for x86 performance improvement. For performance
optimization hints on x86 GCC, refer to Intel's article titled <a
href="http://software.intel.com/blogs/2012/09/26/gcc-x86-performance-hints">GCC
x86 Performance</a>. Also, to investigate what other flags may be useful,
especially <code>-f*</code> and <code>-m</code>, see <a
href="https://gcc.gnu.org/onlinedocs/gcc/i386-and-x86-64-Options.html#i386-and-x
86-64-Options">GCC online documentation: Intel 386 and AMD x86-64
Options</a>.</p>
<ul>
<li>Use of the standard Linux x86 32-bit calling convention, as opposed to the
SVR4 one. (For more information, see section 6, "Register Usage" of <a
href="http://www.agner.org/optimize/calling_conventions.pdf">Calling
conventions for different C++ compilers and operating systems</a>.)</li>
</ul>
<p>The ABI does <em>not</em> include any other optional IA-32 instruction set
extensions, including, but not limited to:</p>
<ul>
<li>The MOVBE instruction.</li>
<li>Any variant of SSE4.</li>
</ul>
<p>You can still use these, as long as you use runtime feature-probing to
enable them, and provide fallbacks for devices that do not support them.</p>
<p>The NDK toolchain assumes 16 byte stack alignment. Tools and options used by
default enforce this rule. It is the user's responsibilty to ensure that stack
alignment is maintained if they write assembly code, and to ensure that other
compilers also obey this rule.</p>
<p>Please refer to the following documents for more details:</p>
<ul>
<li><a
href="https://gcc.gnu.org/onlinedocs/gcc/i386-and-x86-64-Options.html#i386-and-x
86-64-Options">GCC online documentation: Intel 386 and AMD x86-64
Options</a></li>
<li><a href="http://www.agner.org/optimize/calling_conventions.pdf">Calling
conventions for different C++ compilers and operating systems</a></li>
<li><a
href="http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-
32-architectures-software-developer-instruction-set-reference-manual-325383.pdf"
>Intel IA-32 Intel Architecture Software Developer's Manual, Volume 2:
Instruction Set Reference</a></li>
<li><a
href="http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-
32-architectures-software-developer-system-programming-manual-325384.pdf">Intel
IA-32 Intel Architecture Software Developer's Manual, Volume 3: System
Programming Guide</a></li>
<li>Amendment to System V Application Binary Interface: Intel386 Processor
Architecture Supplement</li>
</ul>
<p><a class="anchor" id="86-64"></a> </p>
<h3>x86_64</h3>
<p>This ABI is for CPUs supporting the instruction set commonly referred to as
"x86-64." It supports instructions normally generated by GCC with the following
compiler flags: </p>
<pre class="fragment">-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel
</pre><p>These flags target the x86-64 instruction set, according to the GCC
documentation. along with the MMX, SSE, SSE2, SSE3, SSSE3, <a
href="http://en.wikipedia.org/wiki/SSE4">SSE4.1</a>,SSE4.2, and POPCNT
instruction-set extensions. The generated code is a balanced optimization
across the top Intel 64-bit CPUs.</p>
<p><b>NOTE:</b> The compiler flags shown above do not represent a comprehensive
list. In particular, they do not include compiler optimization options used by
default and/or recommended for x86-64 performance improvement. For performance
optimization hints on x86-64 GCC, refer to Intel's article titled <a
href="http://software.intel.com/blogs/2012/09/26/gcc-x86-performance-hints">GCC
x86 Performance</a>.</p>
<p>The ABI does <em>not</em> include any other optional x86-64 instruction set
extensions, including, but not limited to:</p>
<ul>
<li>the MOVBE instruction</li>
<li>the SHA instruction</li>
<li>the AVX extension</li>
<li>the AVX2 extension</li>
</ul>
<p>You can still use these, as long as you use runtime feature probing to
enable them, and provide fallbacks for devices that do not support them.</p>
<p>Please refer to the following documents for more details:</p>
<ul>
<li><a href="http://www.agner.org/optimize/calling_conventions.pdf">Calling
conventions for different C++ compilers and operating systems</a></li>
<li><a
href="http://www.intel.com/content/www/us/en/processors/architectures-software-d
eveloper-manuals.html?iid=tech_vt_tech+64-32_manuals">Intel64 and IA-32
Architectures Software Developer's Manual, Volume 2: Instruction Set
Reference</a></li>
<li><a
href="http://www.intel.com/content/www/us/en/processors/architectures-software-d
eveloper-manuals.html?iid=tech_vt_tech+64-32_manuals">Intel64 and IA-32 Intel
Architecture Software Developer's Manual Volume 3: System Programming</a></li>
<li>Amendment to System V Application Binary Interface AMD64 Processor
Architecture Supplement</li>
</ul>
<p><a class="anchor" id="mips"></a> </p>
<h3>mips</h3>
<p>This ABI is for MIPS-based CPUs that support <b>at least</b> the MIPS32r1
instruction set. It includes the following features:</p>
<ul>
<li>MIPS32 revision 1 ISA</li>
<li>Little-endian</li>
<li>O32</li>
<li>Hard-float</li>
<li><p class="startli">No DSP application-specific extensions</p>
<p class="startli">For more information, please refer to the following
documentation.</p>
</li>
<li>ELF for the MIPS Architecture ("MIPSELF")</li>
<li>FAQ for MIPS Toolchains ("MIPSFAQ")</li>
<li>Toolchain Specifics ("MIPSTOOL")</li>
<li>SDE Library ("MIPSSDE")</li>
<li>Instruction Set Quick Reference ("MIPSISA")</li>
<li>Architecture for Programmers ("MIPSARCH")</li>
<li><a href="https://refspecs.linuxbase.org/elf/gabi4+/contents.html">ELF
System V Application Binary Interface: DRAFT - 24 April 2001</a></li>
<li><p class="startli"><a
href="http://sourcery.mentor.com/public/cxx-abi/abi.html">Generic C++
ABI</a></p>
<p class="startli">The MIPS-specific documentation is available <a
href="http://www.imgtec.com/mips/architectures/mips32.asp">here</a>, with
further information <a
href="https://sourcery.mentor.com/sgpp/lite/mips/portal/target_arch?@action=faq&
amp;target_arch=MIPS">here</a>.</p>
</li>
</ul>
<p><b>NOTE::</b> This ABI assumes a CPU:FPU clock ratio of 2:1 for maximum
compatibility.</p>
<p><b>NOTE::</b> Neither MIPS16 nor micromips is provided.</p>
<p><a class="anchor" id="mips64"></a> </p>
<h3>mips64</h3>
<p>This ABI is for MIPS64 R6.</p>
<p><a class="anchor" id="gc"></a> </p>
<h2>Generating code for a specific ABI</h2>
<p>By default, the NDK generates machine code for the armeabi ABI. You can
generate ARMv7-a-compatible machine code, instead, by adding the following line
to your <code>Application.mk</code> file.</p>
<pre class="fragment">    APP_ABI := armeabi-v7a
</pre><p>It is also possible to build machine code for two or more distinct
ABIs, using spaces as delimiters. For example:</p>
<pre class="fragment">    APP_ABI := armeabi armeabi-v7a
</pre><p>This instructs the NDK to build two versions of your machine code: one
for each ABI listed on this line. The build system copies the libraries to your
application project path, and ultimately packages them into your APK, creating
a <a href="http://en.wikipedia.org/wiki/Fat_binary">fat binary</a>.</p>
<p>At installation time, the package manager unpacks only the most appropriate
machine code for the target device. For details, see <a href="#aen">Automatic
extraction of native code at install time</a>.</p>
<p>You can also generate machine code for all NDK-supported ABIs:</p>
<pre class="fragment">    APP_ABI := all
</pre><p>Doing so will ensure that your app package contains libraries for all
target ABIs. The tradeoff is that a fat binary is larger than one for a single
system.</p>
<p><a class="anchor" id="am"></a> </p>
<h2>ABI Management on the Android platform</h2>
<p>This section provides details about how the Android platform manages native
code in APKs.</p>
<h3>Native code in app packages</h3>
<p>Both the Play Store and Package Manager expect to find NDK-generated
libraries on filepaths inside the APK matching the following pattern:</p>
<pre class="fragment">   lib/&lt;abi&gt;/lib&lt;name&gt;.so
</pre><p>&lt;abi&gt; is one of the ABI names listed in the <a
href="#sa">Supported ABIs</a> section of this document, and &lt;name&gt; is the
name that the app uses to load the library from the VM. For example:</p>
<pre class="fragment">    System.loadLibrary("&lt;name&gt;");
</pre><p>Since APK files are just zip files, it is trivial to examine them and
confirm that the shared native libraries are where they belong.</p>
<p>If the native shared libraries are not where the system expects to find
them, it can't do anything with them. In such a case, the app itself has to
copy the libraries over, and perform <code>dlopen()</code>.</p>
<p>Multiple libraries can be placed into a fat binary. For example:</p>
<pre class="fragment">    lib/armeabi/libfoo.so
    lib/armeabi-v7a/libfoo.so
    lib/arm64-v8a/libfoo.so
    lib/x86/libfoo.so
    lib/x86_64/libfoo.so
    lib/mips/libfoo.so
    lib/mips64/libfoo.so
</pre><p><b>NOTE::</b> ARMv7-based Android devices running 4.0.3 or earlier
install native libraries from the 'armeabi' directory instead of the
'armeabi-v7a' directory if both exist. <code>lib/armeabi</code> is listed after
<code>lib/armeabi-v7a</code> in APK. This issue is fixed from 4.0.4.</p>
<h3>Android Platform ABI support</h3>
<p>The Android system knows at runtime which ABI(s) it supports, because either
one or two build-specific system properties indicate:</p>
<ul>
<li>The "primary" ABI for the device, corresponding to the machine code used in
the system image itself.</li>
<li>An optional "secondary" ABI, corresponding to another ABI that is also
supported by the system image.</li>
</ul>
<p>To achieve the best performance for your NDK component, you should compile
directly for the primary ABI.</p>
<p>For example, a typical ARMv5TE-based device would only define the primary
ABI: armeabi. By contrast, a typical ARMv7-based device would define the
primary ABI as armeabi-v7a and the secondary one as armeabi, since it can run
application native binaries generated for each of them.</p>
<p>Many x86-based devices can also run armeabi-v7a and armeabi NDK binaries,
and defining the primary ABI as x86 and the secondary one as armeabi-v7a.</p>
<p>A typical MIPS-based device only defines a primary abi: mips.</p>
<p><a class="anchor" id="aen"></a> </p>
<h3>Automatic extraction of native code at install time</h3>
<p>When installing an application, the package manager service scans the APK,
and looks for any shared library of the form:</p>
<pre class="fragment">     lib/&lt;primary-abi&gt;/lib&lt;name&gt;.so
</pre><p>If none is found, and a secondary ABI is defined, the service scans
for shared libraries of the form: </p>
<pre class="fragment">    lib/&lt;secondary-abi&gt;/lib&lt;name&gt;.so
</pre><p>When it finds libraries that it's looking for, the package manager
copies them to <code>/lib/lib&lt;name&gt;.so</code>, under the application's
data directory (<code>/data/data/&lt;package_name&gt;/lib/</code>). If there is
no <code>.so</code> file, the application builds and installs, but crashes at
runtime.</p>
<p>This mechanism ensures that the system extracts the best machine code from
the package at installation time. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Wed Jun 25 2014 00:51:19 for NDK
Programmer&#39;s Guide by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.5 </li>
  </ul>
</div>
</body>
</html>
